<!-- 框选时间段组件 -->
<script>
import * as  defaultJs from './js/index.js'
import { pointSort, changeDomStyle } from './js/index.js'

let curEvent = null
export default {
  model: {
    prop: 'value',
    event: 'change'
  },
  props: {
    value: { type: Array, default: () => ([]) }
  },
  data() {
    return {
      key: 'key_' + Math.random(),
      dataWithIndex: JSON.parse(JSON.stringify(defaultJs.dataWithIndex)),
      dataSouce: JSON.parse(JSON.stringify(defaultJs.dataSouce)),
      columns: JSON.parse(JSON.stringify(defaultJs.columns)),
      colors: {
        enabledColor: '#61a3ff',
        disabledColor: '#ffffff'
      },
      penColors: {
        enabledColor: '#1677ff99',
        disabledColor: '#e3e3e3'
      },
      drawBox: false,
      startXY: [],
      startFlag: [],
      type: 'enabled'
    }
  },
  watch: {
    value: {
      handler(newVal, oldVal) {
        if (JSON.stringify(newVal) !== JSON.stringify(oldVal)) {
          this.$nextTick(() => {
            this.backshow()
          })
        }
      },
      immediate: true,
      deep: true
    }
  },
  mounted() {
    this.clearColor()
    window.addEventListener('mouseup', this.clearKuang)
  },
  beforDestroyed() {
    window.removeEventListener('mouseup', this.clearKuang)
  },
  methods: {
    // 回显逻辑
    backshow() {
      const keys = ['t0a', 't0b', 't1a', 't1b', 't2a', 't2b', 't3a', 't3b', 't4a', 't4b', 't5a', 't5b', 't6a', 't6b', 't7a', 't7b', 't8a', 't8b', 't9a', 't9b', 't10a', 't10b', 't11a', 't11b', 't12a', 't12b', 't13a', 't13b', 't14a', 't14b', 't15a', 't15b', 't16a', 't16b', 't17a', 't17b', 't18a', 't18b', 't19a', 't19b', 't20a', 't20b', 't21a', 't21b', 't22a', 't22b', 't23a', 't23b']
      function getIndexs(key) {
        const list = key.split(':')
        const t = list[1] === '30' ? 0 : 1
        const first = (parseInt(list[0]) + t) * 2
        const sec = list[1] === '30' ? 1 : 0
        return first + sec
      }
      const indexList = this.value.map(item => ({
        index: item.dayOfWeek - 1,
        ctx: [getIndexs(item.beginTime), getIndexs(item.endTime) - 1]
      }))
      indexList.forEach((item) => {
        keys.forEach((ele, i) => {
          if (i > item.ctx[0] - 1 && i < item.ctx[1] + 1) {
            this.dataSouce[item.index][keys[i]] = 'enabled'
          }
        });
      })
      this.changeTrBg() // 修改对应格子的背景颜色
    },
    clearColor() {
      for (let i = 0; i < this.dataSouce.length; i++) {
        const object = this.dataSouce[i];
        for (const key in object) {
          if (Object.hasOwnProperty.call(object, key) && key !== 'week') {
            object[key] = ''
          }
        }
      }
    },
    // 鼠标按下
    mousedown(event) {
      const el = event.target
      const list = el.innerText.split('-')
      const x = Number(list[0]) * 2 + Number(list[1])
      const y = Number(list[2])
      // 记录起始位置的坐标[x,y]
      this.startFlag = [x, y]
      if (!isNaN(x)) {
        // 改变框的起始位置
        this.drawBox = true
        const styles = {
          opacity: '1',
          left: `${event.pageX}px`,
          top: `${event.pageY}px`
        }
        this.startXY = [event.pageX, event.pageY]
        changeDomStyle(styles, this.$refs.kuang)
      }
    },
    // 鼠标移动
    mousemove(event) {
      curEvent = event
      if (this.drawBox) {
        const styles = {}
        const x1 = parseInt(this.startXY[0])
        const y1 = parseInt(this.startXY[1])
        const x2 = event.pageX
        const y2 = event.pageY
        const res = pointSort([x1, y1], [x2, y2])
        const width = res[1][0] - res[0][0]
        const height = res[1][1] - res[0][1]
        styles['left'] = `${res[0][0]}px`
        styles['top'] = `${res[0][1]}px`
        styles['width'] = `${width}px`
        styles['height'] = `${height}px`
        styles['background-color'] = this.penColors[this.type + 'Color']
        styles['border'] = `1px solid ${this.colors[this.type + 'Color']}`
        changeDomStyle(styles, this.$refs.kuang)
      }
    },
    // 鼠标松开
    mouseup(event) {
      const el = event.target
      const list = el.innerText.split('-')
      const x = Number(list[0]) * 2 + Number(list[1])
      const y = Number(list[2])
      // 记录结束位置的坐标[x,y]
      const endFlag = [x, y]
      // 判断起始和结束是否在规定表格内
      const flag2 = !isNaN(this.startFlag[0]) && !isNaN(this.startFlag[1]) && !isNaN(endFlag[0]) && !isNaN(endFlag[1])
      if (flag2) {
        // 将起始坐标、终点坐标排序
        const res = pointSort(endFlag, this.startFlag)
        // 判断起始坐标、终点坐标是否为同一格
        if (JSON.stringify(res[0]) === JSON.stringify(res[1])) {
          const item = this.dataSouce[res[0][1]]
          const key = Object.keys(item)[res[0][0] + 1]
          this.dataSouce[res[0][1]][key] = this.type
        } else {
          // 将起始坐标到终点坐标四边形内覆盖的所有格子赋值
          this.dataSouce.forEach((item, i) => {
            const maxY = res[1][1] + 1
            const minY = res[0][1] - 1
            const maxX = res[1][0] + 2
            const minX = res[0][0]
            if (i < maxY && i > minY) {
              const keys = Object.keys(item)
              keys.forEach((key, j) => {
                if (j < maxX && j > minX) {
                  this.dataSouce[i][key] = this.type
                }
              })
            }
          })
        }
        this.startFlag = [] // 清空起始坐标
        this.clearKuang() // 清除框相关数据
        this.changeTrBg() // 修改对应格子的背景颜色
      }
    },
    // 清除框相关数据
    clearKuang() {
      this.drawBox = false // 关闭画框功能
      this.$nextTick(() => {
        this.$refs.kuang.style = 'opacity: 0'
      })
    },
    // 通知父组件修改数据
    returnResult() {
      const keys = ['t0a', 't0b', 't1a', 't1b', 't2a', 't2b', 't3a', 't3b', 't4a', 't4b', 't5a', 't5b', 't6a', 't6b', 't7a', 't7b', 't8a', 't8b', 't9a', 't9b', 't10a', 't10b', 't11a', 't11b', 't12a', 't12b', 't13a', 't13b', 't14a', 't14b', 't15a', 't15b', 't16a', 't16b', 't17a', 't17b', 't18a', 't18b', 't19a', 't19b', 't20a', 't20b', 't21a', 't21b', 't22a', 't22b', 't23a', 't23b']
      function getHour(key) {
        const list = key.split('')
        if (list.length === 3) {
          const num = '0' + list[1]
          const hou = { a: ':00', b: ':30' }[list[2]]
          if (hou === ':00' && num !== '00') {
            return '0' + (num - 1) + ':59:59'
          }
          return num + hou + ':00'
        } else {
          const num = list[1] + list[2]
          const hou = { a: ':00', b: ':30' }[list[3]]
          if (hou === ':00' && num !== '00') {
            return num === '10' ? '09:59:59' : (Number(num) - 1) + ':59:59'
          }
          return num + hou + ':00'
        }
      }
      const res2 = []
      let res = []
      this.dataSouce.forEach((item, i) => {
        keys.forEach((key, j) => {
          if (item[key] === 'enabled') {
            res.push(getHour(key))
            if (keys[j + 1]) {
              res.push(getHour(keys[j + 1]))
            } else {
              res.push(getHour('t24a'))
              res.length > 0 && res2.push({
                beginTime: res[0],
                endTime: res[res.length - 1],
                dayOfWeek: i + 1
              })
              res = []
            }
          } else {
            res.length > 0 && res2.push({
              beginTime: res[0],
              endTime: res[res.length - 1],
              dayOfWeek: i + 1
            })
            res = []
          }
        });
      });
      this.$emit('change', res2)
    },
    // 修改对应格子的背景颜色
    changeTrBg() {
      const main = document.getElementsByClassName('config-set-box-' + this.key)[0]
      const trDoms = main.getElementsByClassName('el-table__row')
      const children = []
      for (let i = 0; i < trDoms.length; i++) {
        const element = trDoms[i];
        const list = element.childNodes
        children.push(list)
      }
      for (let i = 0; i < this.dataSouce.length; i++) {
        const element = this.dataSouce[i];
        const keys = Object.keys(element)
        for (let j = 0; j < keys.length; j++) {
          const key = keys[j];
          const color = (this.colors[`${element[key]}Color`]) || ''
          if (children[i][j]) {
            children[i][j].style = `background-color: ${color} !important;text-align: center;`
          }
        }
      }
      this.returnResult()
    },
    mouseleave() {
      this.mouseup(curEvent)
    }
  }
}
</script>

<template>
  <div :class="`config-set-box config-set-box-${key}`">
    <el-switch
      v-model="type"
      active-text="框选时间"
      inactive-text="橡皮擦"
      active-value="enabled"
      inactive-value="disabled"
      style="margin-bottom: 10px;"
    />
    <div class="table-main" @mousedown="mousedown" @mousemove="mousemove" @mouseup="mouseup" @mouseleave="mouseleave">
      <el-table :data="dataWithIndex" size="mini" bordered :row-key="(r) => r.index">
        <el-table-column
          v-for="(item, i) of columns"
          :key="i"
          width="100px"
          align="center"
          :label="item.title + ''"
          prop="week"
        >
          <el-table-column
            v-for="(ele, j) of item.children"
            :key="'c' + j"
            width="35px"
            align="center"
            :label="ele.title + ''"
          >
            <el-table-column
              v-for="(ch, k) of ele.children"
              :key="'cc' + k"
              width="20px"
              align="center"
              :label="ch.title + ''"
              :prop="ch.dataIndex"
            />
          </el-table-column>
        </el-table-column>
      </el-table>
    </div>
    <div ref="kuang" class="kuang-box" style="opacity: 0" />
  </div>
</template>

<style lang="scss" scoped>
  .config-set-box {
    user-select: none;

    .label {
      font-size: 20px;
      font-weight: 600;
    }

    .table-main {
      width: fit-content;
    }
  }
</style>
<style lang="scss">
  .config-set-box {
    .kuang-box {
      position: fixed;
      pointer-events: none;
    }

    .is-group {
      tr {
        line-height: 10px !important;
        height: 10px !important;

        th div {
          padding: 0 !important;
        }
      }
    }

    .el-table__row td {
      padding: 0 !important;
    }

    .el-table__row td:not(:first-child) .cell {
      white-space: nowrap;
      transform: scale(0);
    }
  }
</style>
